pub mod types;
pub mod utils;
pub mod init;
pub mod prim;
pub mod heap;
pub mod page;
pub mod segment;
pub mod alloc;

pub use types::*;
pub use init::*;
pub use utils::*;
pub use prim::*;
pub use heap::*;
pub use page::*;
pub use segment::*;
pub use alloc::*;

use core::alloc::{GlobalAlloc, Layout};
use std::{ptr, sync::atomic::Ordering};


const PAGE_SIZE: usize = 4096;

pub struct MyAllocator;

impl MyAllocator {
    pub fn mi_register_deferred_free(&self, f: fn(bool, u64)) {
        mi_register_deferred_free(f);
    }

    pub fn mi_malloc(&self, size: usize) -> *mut u8 {
        mi_heap_malloc(get_heap_default(), size)
    }

    /// Free a block
    pub fn mi_free(&self, ptr: *mut u8) {
        _mi_free(ptr);
    }

    pub fn mi_collect(&self, force: bool) {
        mi_heap_collect(get_heap_default(), force);
    }
}

unsafe impl GlobalAlloc for MyAllocator {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        self.mi_malloc(layout.size())
    }
    unsafe fn dealloc(&self, ptr: *mut u8, _: Layout) {
        // mi_free a block, layout is ignored
        self.mi_free(ptr);
    }
}
